#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <crc.h>
#include <algorithm>
#define _MY_STL_MACROS
#include <stlhelper.h>

using std::cerr;
using std::string;
using std::ostringstream;
using std::ofstream;
using std::ifstream;
using std::vector;
using std::getline;
using std::sort;

string usage =
"Usage:\n\n"
"    find_duplicate_rows <FILENAME>\n"
"\n"
"    This programme goes through all the rows in a text file \n"
"        and prints duplicates.\n\n";

struct crc_file_pos
{
	t_crc_hash	crc;
	unsigned	pos;
	crc_file_pos(const t_crc_hash& crc_, unsigned pos_): crc(crc_), pos(pos_){}
};
inline bool operator < (const crc_file_pos& a, const crc_file_pos& b)
{
	return(a.crc < b.crc);
}
inline bool operator == (const crc_file_pos& a, const crc_file_pos& b)
{
	return(a.crc == b.crc);
}

typedef vector<crc_file_pos>::iterator iter_fpos;
	
struct print_duplicate_row
{
	ifstream& is;
	print_duplicate_row(ifstream& is_) : is(is_){}
	void operator()(const crc_file_pos& i)
	{
		is.seekg(i.pos);
		string line;
		getline(is, line);
		cerr << line << "\n";
	}
};
//8888888888888888888888888888888888888888888888888888888888888888888888888888

//	Main

//8888888888888888888888888888888888888888888888888888888888888888888888888888
int main(int argc, char* argv[])
{
	init_crc_hash();
	cerr << "\n";
	if (argc != 2)
	{
		cerr << usage;
		return 1;
	}
	ifstream is (argv[1]);
	if (!is)
	{
		cerr << "Error: " << argv[1] << "\n: File is not valid!\n\n";
		return(1);
	}

	vector<crc_file_pos> vec_filepos;
	string line;
	unsigned file_pos = 0;
	while (is)
	{
		getline(is, line);
		vec_filepos.push_back(crc_file_pos(crc_hash(line), file_pos));
		file_pos += line.length() + 1;
		cerr << crc_hash(line) << "\n";
	}
	
	is.clear();
	is.seekg(0);	

	std::sort(beg_to_end(vec_filepos));
	mark_consecutive_duplicates(beg_to_end(vec_filepos), print_duplicate_row(is));
	

	return(0);
	
}	


